#pragma once
#include "utils.hpp"
#include <unordered_map>

namespace Cloud
{
	const char* const backupFile = "cloud.dat";
	class DataManager
	{
	public:
		DataManager()
			:_backupFile(backupFile)
		{
			checkFile();
			init();
		}
		void checkFile()
		{
			if (FileUtils(_backupFile).exists() == false)
				FileUtils(_backupFile).setContent("");
		}

		void init()
		{
			std::ifstream ifs(_backupFile, std::ios::binary);
			std::string filePath;
			while (std::getline(ifs, filePath))
			{
				std::string fileInfo;
				std::getline(ifs, fileInfo);
				_hash[filePath] = fileInfo;
				std::getline(ifs, fileInfo);
			}
		}
		bool storage()
		{
			std::stringstream ss;
			for (const auto& e : _hash)
				ss << e.first << "\n" << e.second << "\n\n";
			std::ofstream ofs(_backupFile, std::ios::binary);
			if (!ofs)
			{
				std::cerr << "DataManager::storage: open file error\n";
				return false;
			}
			ofs << ss.str();
			return true;
		}

		bool insert(const std::string& filePath, const std::string& fileInfo)
		{
			_hash[filePath] = fileInfo;
			return storage();
		}

		bool update(const std::string& filePath, const std::string& fileInfo)
		{
			_hash[filePath] = fileInfo;
			return storage();
		}

		bool getInfoFromHash(const std::string& filePath, std::string* fileInfo)
		{
			if (_hash.count(filePath))
			{
				*fileInfo = _hash[filePath];
				return true;
			}
			return false;
		}
		bool getInfoFromDir(const std::string& filePath, std::string* fileInfo)
		{
			FileUtils tmp(filePath);
			if (tmp.exists())
			{
				*fileInfo += std::to_string(tmp.getMTime());
				*fileInfo += "***";
				*fileInfo += tmp.getFileName();
				return true;
			}
			return false;
		}
	private:
		std::unordered_map<std::string, std::string> _hash;
		std::string _backupFile;
	};
	static DataManager dataManager;
}